package com.hzhh123.crypto.processor;

import com.hzhh123.crypto.annotation.CryptoType;
import com.hzhh123.crypto.handle.CryptoContext;
import com.hzhh123.crypto.utils.spring.ClassScanner;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;

import java.util.HashMap;
import java.util.Map;

/**
 * @author hzhh123
 * @version 1.0
 * @date 2022/4/15 17:00
 * @des
 */
@Slf4j
public class CryptoBeanFactoryPostProcessor implements EnvironmentAware,BeanFactoryPostProcessor {
    private final static String HANDLE_PACKAGE = "com.hzhh123.crypto.handle";
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        Map<String, Class<?>> handleMap = new HashMap<>(8);
        ClassScanner.scan(HANDLE_PACKAGE, CryptoType.class).forEach(clazz -> {
            String value = clazz.getAnnotation(CryptoType.class).value();
            handleMap.put(value, clazz);
        });
        //扫描外部包，直接从CryptoProperties中获取不到属性
        String scanOuterCryptoPackage = environment.getProperty("crypto.scan-outer-package");
        if(StringUtils.isNotBlank(scanOuterCryptoPackage)){
            log.info("扫描加解密外部包(crypto.scan-outer-package){}",scanOuterCryptoPackage);
            String[] scanOuterCryptoPackages = scanOuterCryptoPackage.split(",");
            ClassScanner.scan(scanOuterCryptoPackages, CryptoType.class).forEach(clazz -> {
                String value = clazz.getAnnotation(CryptoType.class).value();
                handleMap.put(value, clazz);
            });
        }
        log.info("默认支持加解密方式:{}",handleMap.keySet());
        CryptoContext cryptoContext = new CryptoContext(handleMap);
        configurableListableBeanFactory.registerSingleton(CryptoContext.class.getName(), cryptoContext);
    }


    private ConfigurableEnvironment environment;
    @Override
    public void setEnvironment(Environment environment) {
        this.environment = (ConfigurableEnvironment) environment;
    }
}
